/*
 * @Description:
 * @Version: 2.0
 * @Autor: wiz
 * @Date: 2023-12-19 10:26:29
 * @LastEditors: zss
 * @LastEditTime: 2024-06-28 08:51:07
 */
import { N_oSetupPanel } from '@/types';

import { Tsrv } from '@/services';
import { T_data } from './data';

// 注册要徙理的外部方法
export interface I_regHandleFunction {
  // 临时控制按钮显示状态
  setTempToolbarStatusDisabled: (
    p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
  ) => void;

  // 还原临时控制按钮显示状态
  setTempToolbarStatusUnDisabled: (
    p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
  ) => void;

  // 清除子组件内容
  cleanSubCompData: (
    p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
  ) => void;
  // 设置组件全遮罩
  setMask: (boolean) => void;
}
// 当前组件实例
export class T_compCoordination extends T_data {
  private actToolbarRegex = new RegExp(
    /^(insert|delete|audit|unAudit|edit|unEdit|save|refresh)$/
  );

  // 功能名
  private funName: string = null;

  // 当前组件自己监听的协作事件ID
  private currCompCoordination: string = null;

  // 消息配置
  private messageConf: N_oSetupPanel.N_comps.I_messageConf;

  // 处理方法注册
  private regHandleFunction: I_regHandleFunction;

  private allCoordinations: Set<string> = null;

  constructor(
    funName: string,
    msgConf: N_oSetupPanel.N_comps.I_messageConf,
    regHandleFun: I_regHandleFunction
  ) {
    super();
    this.messageConf = msgConf;
    this.funName = funName;
    this.regHandleFunction = regHandleFun;
    this.currCompCoordination = msgConf.custDefListener.coordination;
    this.getToIDs();
  }

  // 处理组件协调
  public receEventCoordination(
    m: N_oSetupPanel.N_comps.I_eventCoordinationMsg
  ): Promise<[boolean, string]> {
    return new Promise((resolve, reject) => {
      if (this.actToolbarRegex.test(m.action.toolbar)) {
        const er = this.receEventHandle(m);
        if (er === '') {
          resolve([true, er]);
        } else {
          reject([false, er]);
        }
      } else {
        reject([false, `-118,FE,90,*${m.action.toolbar}#`]);
      }
    });
  }

  // 处理组件协调 返回 true/false msg=[错误消息/成功消息]
  public sendEventCoordination(
    t: N_oSetupPanel.N_comps.T_eventCoordinationToolbar,
    eventBus: any
  ): Promise<[boolean, string]> {
    return new Promise((resolve, reject) => {
      if (!this.messageConf) {
        reject([false, `-119,FE,90,数据空[messageConf]`]);
      }
      if (!this.messageConf?.eventGroup) {
        reject([false, `-119,FE,90,数据空[messageConf.eventGroup]`]);
      }
      if (!this.currCompCoordination) {
        reject([false, `-119,FE,90,数据空[currCompCoordination]`]);
      }
      const m: N_oSetupPanel.N_comps.I_eventCoordinationMsg = {
        type: 'coordination',
        fromComp: {
          funName: this.funName,
          fromEvenID: this.messageConf.custDefListener.coordination
        },
        action: {
          toolbar: t
        }
      };
      if (this.allCoordinations !== null && this.allCoordinations.size > 0) {
        this.allCoordinations.forEach(toID => {
          if (toID !== this.currCompCoordination) {
            Tsrv.reliablySendingBusEvent(toID, eventBus, 10, 100, m);
          }
        });
      }

      resolve([true, '200,FE,90']);
    });
  }

  // 处理组件协调
  private receEventHandle(
    m: N_oSetupPanel.N_comps.I_eventCoordinationMsg
  ): string {
    let msg = '';
    const t = m.action.toolbar;
    switch (t) {
      case 'insert':
        this.regHandleFunction.setTempToolbarStatusDisabled(t);
        this.regHandleFunction.setMask(true);
        // 是发起方的儿子就刷新
        if (
          this.getToIDs(m.fromComp.fromEvenID).has(this.currCompCoordination)
        ) {
          this.regHandleFunction.cleanSubCompData(t);
        }

        break;
      case 'delete':
        this.regHandleFunction.setMask(true);
        break;
      case 'unAudit':
        break;
      case 'edit':
        this.regHandleFunction.setTempToolbarStatusDisabled(t);
        this.regHandleFunction.setMask(true);

        break;
      case 'unEdit':
        this.regHandleFunction.setTempToolbarStatusUnDisabled(t);
        this.regHandleFunction.setMask(false);

        break;
      case 'save':
        this.regHandleFunction.setTempToolbarStatusUnDisabled(t);
        this.regHandleFunction.setMask(false);

        break;
      case 'audit':
        break;
      case 'refresh':
        this.regHandleFunction.setTempToolbarStatusUnDisabled(t);
        this.regHandleFunction.setMask(false);
        break;
      default:
        // throw new Error(`无法识别的事件属性[${m.action.toolbar}]`);
        msg = `-118,FE,90,*${t}#`;
    }
    return msg;
  }

  private getToIDs(custBeginEventID: string = null): Set<string> {
    if (
      this.utils.noValue(custBeginEventID) &&
      this.allCoordinations !== null &&
      this.allCoordinations.size > 0
    ) {
      return this.allCoordinations;
    }
    // let toIDs: Set<string> = null;
    let toIDs: Set<string> = new Set<string>();
    if (!Tsrv.utils.noValue(this.messageConf?.eventGroup)) {
      Object.keys(this.messageConf.eventGroup).forEach(key => {
        const eg = this.messageConf.eventGroup[key];
        toIDs = this.getIds(eg, custBeginEventID);
        if (this.utils.noValue(custBeginEventID)) {
          toIDs.add(eg.custDefListener.coordination);
          this.allCoordinations = toIDs;
        }
      });
    }

    return toIDs;
  }

  private getIds(
    eg: {
      custDefListener: N_oSetupPanel.N_comps.I_custDefListener;
      children: Array<N_oSetupPanel.N_comps.I_eventGroup>;
    },
    custBeginEventID: string = null,
    beginRecord: boolean = false, // typ === 'curr'从指定的数据开始查找时允许的有效ID
    cn: number = 100 // 防止死循环
  ): Set<string> {
    --cn;
    if (cn <= 0) {
      throw new Error('在解析协作ID时死循环');
    }
    const toIDs: Set<string> = new Set();
    if (eg.custDefListener.coordination === custBeginEventID) {
      beginRecord = true; // 开始记录
    }

    if (this.utils.noValue(custBeginEventID)) {
      beginRecord = true; // 开始记录
    }
    if (!this.utils.noValue(eg.children)) {
      eg.children.forEach(e => {
        Object.keys(e).forEach(k => {
          if (this.currCompCoordination !== e[k].custDefListener.coordination) {
            if (beginRecord) {
              toIDs.add(e[k].custDefListener.coordination);
            }
          }
          const child = e[k].children;
          if (!this.utils.noValue(child)) {
            const eids = this.getIds(e[k], custBeginEventID, beginRecord, cn);
            if (beginRecord) {
              eids.forEach(id => {
                toIDs.add(id);
              });
            }
          }
        });
      });
    }
    return toIDs;
  }
}

export interface I_compCoordination extends T_compCoordination {}
